home *** CD-ROM | disk | FTP | other *** search
/ Sound Fx / Sound Fx.iso / Software / UNZIPED / DWSTKW / DOC / WINSTK.TXT < prev   
Text File  |  1996-09-23  |  88KB  |  2,059 lines

  1. This document is pure ASCII text format; it may be viewed in any text editor,
  2. or by the "type" command at a DOS prompt.  It's not really optimized for
  3. printout; if you want a hardcopy, we really recommend printing from WINSTK.DOC
  4. (which is in Microsoft Word format).  It will give you nice pagination,
  5. courier monospace and other fonts, a table of contents, an index, etc.
  6.  
  7. DiamondWare's Sound ToolKit for Windows (The WIN-STK) was brought to
  8. you by DiamondWare, Ltd.
  9.  
  10. You can contact us via:
  11.     internet email: support@dw.com
  12.     Web Page:        www.dw.com
  13.     CompuServe:     73704,245
  14.     voice:        (602) 917-3474
  15.     FAX:        (602) 917-5973
  16.     snail-mail:     2095 N. Alma School Rd., Suite 12-288, Chandler, AZ 85224
  17.  
  18. The WIN-STK software was designed and developed by John C. Lundy, Erik 
  19. Lorenzen, and Keith Weiner.
  20.  
  21. Example source code was developed by John Lundy, with language-specific 
  22. help from Dave Allen (Visual BASIC), and David Bollinger (Delphi).
  23.  
  24. This document was written and edited by Keith Weiner.  Proofreading was done 
  25. by Joyce Weiner, Angelo Nunes, Erik Lorenzen, John Lundy, Dave Allen and 
  26. David Bollinger.
  27.  
  28. The Visual BASIC interface was written by Dave Allen.  The Delphi interface 
  29. was written by David Bollinger.
  30.  
  31. This software and documentation are Copyright 1994-1996 DiamondWare,
  32. Ltd.  All rights reserved.  DiamondWare's Sound ToolKit, DiamondWare's
  33. STK, The STK, The WIN-STK, DiamondWare, DW, and DW are trademarks of 
  34. DiamondWare, Ltd.
  35.  
  36. The included sample MIDI song is Copyright 1994 David Schultz, All Rights
  37. Reserved.  Used by permission.  May not be used without written permission 
  38. from David Schultz.
  39.  
  40. DiamondWare also offers a full range of consulting and software development 
  41. services, from device-driver development to turnkey multimedia titles.  Please 
  42. call us for more information.
  43.  
  44. Borland is a registered trademark, and Delphi is a trademark of Borland
  45.   International Inc.
  46. Visual Age is a trademark, and IBM is a registered trademark of IBM Corp.
  47. Microsoft and Win32 are registered trademarks of, and Windows and Visual
  48.   BASIC are trademarks of Microsoft Corporation
  49. Symantec is a trademark of Symantec Corporation
  50. Watcom is a trademark of Watcom Systems, Inc.
  51.  
  52. License Agreement: Commercial Version
  53. This document is a legal agreement between you and DiamondWare, Ltd. By using this software, 
  54. you agree to be bound by the terms of this Agreement and Disclaimer of Warranty and Limited 
  55. Warranty. If you do not agree to the terms of this Agreement, promptly return the software and all 
  56. accompanying items for a full refund.
  57. 1. GRANT OF LICENSE. This License Agreement permits you (one person) to use one copy of the 
  58. enclosed Sound ToolKit for Windows software and documentation (The WIN-STK) on a single 
  59. computer.
  60. 2. COPYRIGHT. The WIN-STK is owned by DiamondWare, Ltd., and is protected by United 
  61. States copyright law and international treaty provisions. You must treat the WIN-STK like any 
  62. other copyrighted work except that you may either (a) make one copy solely for backup or archival 
  63. purposes, or (b) transfer the WIN-STK to your hard disk, provided that you keep the original solely 
  64. for backup or archival purposes. You may not copy the written materials accompanying the WIN-
  65. STK. You may be held legally liable for any copyright infringement that is caused or encouraged 
  66. by your failure to abide by the terms of this Agreement.
  67. 3. OTHER RESTRICTIONS. You may not rent or lease the WIN-STK. It is licensed to you, the 
  68. Licensee. The license may not be transferred to any other party without the prior written consent of 
  69. DiamondWare, Ltd. You may not reverse engineer, decompile, or disassemble the WIN-STK.
  70. 4. DISTRIBUTION. You are hereby granted a royalty-free non-exclusive right to reproduce and 
  71. distribute the WIN-STK DLLs as part of your software, provided that it does not compete with, or 
  72. substantially duplicate the functionality of, the WIN-STK. You must credit the WIN-STK wherever 
  73. your other credits appear.
  74.  
  75. License Agreement: Demo Version
  76. This version of the WIN-STK is SHAREWARE.  DiamondWare grants you a personal license to 
  77. evaluate the WIN-STK for 30 days.  This license is for evaluation purposes only.  You may not 
  78. distribute this SHAREWARE version of the WIN-STK as part of any other software.  In any event, 
  79. after 30 days, you must pay the license fee or stop using the STK.
  80.  
  81. DiamondWare also grants permission to distribute this SHAREWARE version of the WIN-STK 
  82. under the following terms:
  83. 1. You must include all of the files listed in PACKING.LST.
  84. 2. You must make it clear that the WIN-STK is SHAREWARE.
  85.  
  86. Disclaimer of Warranty and Limited Warranty
  87. The WIN-STK diskette and accompanying written materials are sold "as is", without warranty or 
  88. guarantee as to their performance, merchantability, or fitness for any particular purpose. The entire 
  89. risk as to the results and performance of the WIN-STK is assumed by you.
  90. However, the magnetic diskette on which the software is recorded is warranted to be free from 
  91. defects in materials and workmanship under normal use for a period of ninety days from the date of 
  92. purchase. If, during this ninety-day period, the diskette should prove defective, it may be returned 
  93. for a replacement without charge, provided you have registered your WIN-STK license via mail.
  94. Your sole and exclusive remedy in the event of a defect is expressly limited to replacement of the 
  95. diskette, as provided above.
  96. Any implied warranties relating to the diskette, including any implied warranties of 
  97. merchantability and fitness for a particular purpose, are limited to a period of ninety days from the 
  98. date of purchase. Neither DiamondWare, nor its partners, agents, distributors, or contractors, shall 
  99. be liable for indirect, special, or consequential damages resulting from the use of this product.
  100.  
  101. Free Upgrade Policy for Bug Finders
  102. DiamondWare is committed to the goal of zero-defect software.
  103.  
  104. Bug-free programs do not happen by accident.  They are the result of a thorough 
  105. design, a scientific approach to coding, and extensive testing of the finished 
  106. product.  By the time we ship a product, we have more than just a hope that our 
  107. products are robust.  We have an expectation, based on evidence.
  108.  
  109. You shouldn't find any bugs in our code.
  110.  
  111. But if you do, your foremost concern (and ours) is getting the problem fixed 
  112. properly, verifying the fix, and getting you an update.
  113.  
  114. For your trouble, we're prepared to offer you a free upgrade to the next major 
  115. version.  This isn't really adequate payment for your time or aggravation.  But 
  116. it's our way of showing some appreciation for what is otherwise a grueling and 
  117. thankless task.
  118. Conditions
  119.   The defect must be non-trivial.
  120.   You must be the first to report it.
  121.   Upon our request, you must provide us with a test program which 
  122. demonstrates the bug.
  123.   The bug must be caused by DiamondWare's code.
  124.   Cosmetic problems are excluded from this policy, although we'll try to 
  125. provide fixes quickly.
  126.   Operating system or driver bugs are also excluded, although we'll try to 
  127. provide workarounds.
  128.   The final decision, whether or not to award a free upgrade, lies with 
  129. DiamondWare.
  130.  
  131. Please help us make the product better by reporting any problem you encounter 
  132. with DiamondWare software.
  133.  
  134.  
  135. Upgrade Policy
  136. It's our policy to make minor version upgrades available to registered users of 
  137. our products free of charge.
  138.  
  139. Minor version upgrades include bug fixes, performance improvements, 
  140. additional new features, etc.
  141.  
  142. Normally, minor version upgrades are distributed electronically.
  143.  
  144. Major version upgrades will constitute at least one non-trivial new feature, and 
  145. several other features.  A major version means that substantial new code was 
  146. developed; possibly the product was rewritten from the ground up.
  147.  
  148. New major versions are offered to existing customers at a substantial discount; 
  149. in the past, the discount has been 50%.
  150.  
  151.  
  152. Introduction
  153. This manual is organized into three major sections.  The first is the Guide.  
  154. Although you can skip the some of its topics, it contains some invaluable 
  155. information about the WIN-STK, including useful hints and troubleshooting 
  156. help.
  157.  
  158. The second section is the Tutorial.  It will take you step by step through some 
  159. code which uses the STK.  If you're familiar with the DOS-STK, or prefer to 
  160. read the files on disk, you might skip this section; it is not essential.
  161.  
  162. The third section is the Reference.  You might want to skim it before writing 
  163. your code; it's always a good idea to achieve closure with any API you use.
  164.  
  165. Guide to the WIN-STK
  166. This section gives an overview of the product, but also contains some specific 
  167. information, and recommendations.
  168. What Is It?
  169. DiamondWare's Sound ToolKit for Windows (The WIN-STK) is a sound library 
  170. which provides functions to support interactive sound and music.
  171.  
  172. What does this mean? Windows can play MIDI and WAVE files already.
  173.  
  174. That's true.  However, Windows cannot play more than one sound at a time, nor 
  175. even reliably tell you when it's done playing.  The rest of this Guide will discuss 
  176. the feature set of the WIN-STK, and explain how to use it.
  177.  
  178. The WIN-STK is supplied as four DLLs: one for 16- and one for 32-bit Windows
  179. (and two more for Win32s), so it can be used from almost any programming or
  180. authoring environment.    We provide all the files you'll need if you're using
  181. C/C++ from Microsoft, Borland, Watcom, Symantec, or IBM; or if you're using
  182. Visual BASIC, or Delphi.
  183.  
  184. The WIN-STK implements a superset of our acclaimed API, originally 
  185. introduced for the DOS version.  Its architecture will impact yours minimally (if 
  186. at all), so adding the WIN-STK to a mostly-completed program will be easy.
  187.  
  188. The WIN-STK provides an object-oriented sound-centered API, which is 
  189. cleaner and easier to use than a channel-centered system.  With the WIN-STK, 
  190. you don't have to allocate or deallocate channels.
  191.  
  192. The WIN-STK supports (and has been tested under!) Windows 3.1, Windows 
  193. 95, and Windows NT.
  194.  
  195. The WIN-STK requires a minimum platform of a 486.  We recommend a 486-
  196. 66, however.
  197. What Does It Do?
  198. It plays up to sixteen digital sounds (WAVEs) at the same time, plus one MIDI 
  199. song.  Your program selects the digitized mode (mono or stereo, bits/sample, 
  200. and sampling rate) and which MIDI device to use.
  201.  
  202. The salient features of the WIN-STK are listed below.
  203.  
  204. Random Access.  You can start or stop any sound at any time.
  205.  
  206. Low latency.  Latency is the time elapsed between your call to play a sound, 
  207. and when the sound is actually heard.  Typically, for Windows 95 and NT, the 
  208. WIN-STK latency figures are: 100 milliseconds average, 75ms best case, and 
  209. 125ms worst case.  For Windows 3.1, they are 200ms average, 150 best, and 
  210. 250 worst.  This is good enough to convince users that a sight and sound 
  211. occurred simultaneously.  (Though it's probably not good enough for a 
  212. keyboard synthesizer application.)
  213.  
  214. DSP.  You can alter the pitch and volume of each sound.
  215.  
  216. Stereo.  The WIN-STK can play a monophonic (or stereo sound) through both 
  217. stereo output channels, with a different volume in each (panning).
  218.  
  219. Interactivity.  Even after a sound is playing, you can change its pitch and 
  220. volume, loop count, etc.  The WIN-STK can notify you when a sound is done 
  221. playing, giving you the opportunity to display graphics or execute a handler.
  222.  
  223. Sequencing.  The WIN-STK allows you to play a sound right after another, 
  224. guaranteeing that the sequenced sound will play exactly when the first is done, 
  225. without an overlap, click, or pause.
  226.  
  227. Music.  The WIN-STK can play a MIDI song.
  228. Where Is It Going in the Future?
  229. This version of the WIN-STK was released because it provides a valuable 
  230. feature set to many programmers, who are trying to mix several channels of 
  231. digital audio.
  232.  
  233. But it's not the penultimate system.  Here's sneak preview of future WIN-STKs.
  234.  
  235. Better MIDI support.  This includes volume control, callbacks for SysEx and 
  236. other events, multiple songs playing at the same time, segueing, branching, etc.  
  237. In other words, interactive music.
  238.  
  239. DirectSound and Native Audio support.
  240.  
  241. Recording.  A future version will support recording, as well as playback.  Added 
  242. bonus: some boards support simultaneous record/playback, which is perfect for 
  243. networked games!
  244.  
  245. Other features, To Be Determined: If there's something you really want to see, 
  246. please let us know!
  247.  
  248. Development Environments
  249. Before proceeding any further, you should be familiar with such programming 
  250. topics as bitfields and using DLLs.
  251.  
  252. The WIN-STK will work with any development environment which can load 
  253. and call DLLs, however this document discusses C/C++, Visual BASIC, and 
  254. Pascal specifically.
  255. Language Notes for C/C++
  256. The WIN-STK has been tested with compilers from Microsoft, Borland, 
  257. Watcom, Symantec, and IBM.  DWS.H passes through all of them without any 
  258. warnings.  The sample program PLAYSTK also works with all.  However, we 
  259. provide a 16- and 32-bit .LIB file for each compiler.
  260.  
  261. In some compilers, you may need to add the common dialog library into your 
  262. project in order to build PLAYSTK.EXE.  See your compiler's manual for 
  263. details.
  264.  
  265. This manual was written using C terminology, so if you're familiar with ANSI 
  266. C, and a modern commercial Windows compiler, you should be able to read this 
  267. manual with 100% comprehension.
  268.  
  269. As with other libraries, the WIN-STK provides an include file.  Put the line:
  270.  
  271.     #include "dws.h"
  272.  
  273. at the top of every source module which uses the WIN-STK.
  274.  
  275. If you've never written a program using a DLL before, there are two ways to do 
  276. it.  We'll call the first "The Easy Way", and the second "The Hard Way."
  277.  
  278. In The Easy Way, you link with an import library.  This usually comes with the 
  279. DLL, or most compilers provide a utility called IMPLIB.EXE which can make 
  280. one.  The import library provides a stub for each function in the DLL.  It takes 
  281. care of the magic of loading the DLL, determining runtime addresses, etc.
  282.  
  283. The WIN-STK comes with an import library for the most popular compilers; if 
  284. we didn't provide one for your compiler, look for IMPLIB.EXE in your 
  285. compiler's BIN directory.
  286.  
  287. In The Hard Way, you do everything yourself.  You manually load the DLL, 
  288. calculate the address of every function you need within it, and call those 
  289. functions through pointers.  The Hard Way is beyond the scope of this 
  290. documentation, but it's mentioned for completeness.
  291.  
  292. Some programmers use the standard-library function atexit to register 
  293. cleanup functions, which are called before the program terminates.  You must 
  294. not use this facility to call dws_Kill.  This is because Windows 95 and NT 
  295. will wait until all threads except the main thread stop executing.  The WIN-STK 
  296. uses a background thread which is terminated during the call to dws_Kill.  
  297. This will lead to an impasse, where the program will not quite terminate.
  298.  
  299. The atexit problem does not apply to 16-bit programs, but if you think that 
  300. you will ever move to Win32, you should probably avoid it anyway.
  301. Language Notes for Visual BASIC
  302. The WIN-STK supports Visual BASIC 3 and Visual BASIC 4, including the 
  303. new 32-bit mode.
  304.  
  305. In the reference section, you will find a prototype for each WIN-STK function 
  306. in C, Visual BASIC, and Pascal.  However, this document is somewhat C-
  307. centric.
  308.  
  309. Read on for some information which will help you comprehend the rest of the 
  310. manual.
  311.  
  312. In C, all procedures are called "functions", although in Visual BASIC they may 
  313. be "functions" or "subroutines", depending on whether they return a value.
  314.  
  315. In C, variables are declared type first, and then variable name:
  316.  
  317. int x;
  318.  
  319. This declares a variable called x, of type integer.  Pointers are declared with a 
  320. star, like:
  321.  
  322.         int *y;
  323.  
  324. Here, y is a pointer to integer.  Some WIN-STK functions take pointer 
  325. parameters, and the sample C code in this document will use this notation.
  326.  
  327. A C struct, often called a structure, is the equivalent of a Visual BASIC user-
  328. defined Type.
  329.  
  330. C comments are either a double slash //Comment which is a comment until 
  331. the end of the line, equivalent to Visual BASIC's apostrophe ' or REM; or 
  332. /*Comment*/, which is a comment between the /* and the */.
  333.  
  334. C expresses bitwise OR as a pipe |, bitwise AND as an ampersand &, boolean 
  335. OR as two pipes ||, and boolean AND as two ampersands &&.
  336.  
  337. In C, the ampersand & operator can also be used to take the address of a 
  338. variable.  For example:
  339.  
  340. dws_MSongStatus(&mstat);
  341.  
  342. This call passes the address of the variable mstat to dws_MSongStatus.  
  343. By default, Visual BASIC passes parameters by reference, so you probably 
  344. won't have to deal with this issue.
  345.  
  346. In C, the default is to pass a parameter by value, which in VB requires the use of 
  347. the ByVal keyword.
  348.  
  349. To pass a NULL pointer in Visual BASIC, you need to specify a 32-bit 0:
  350.  
  351. dws_DGetInfo(dplay, ByVal 0&);
  352.  
  353. We provide DWS.BAS, which declares all of the constants, data types, and 
  354. routines of the WIN-STK.  Add this file to your project.  You might also want to 
  355. read through it.
  356.  
  357. The WIN-STK can send your window a message when a digitized sound is done 
  358. playing.  But Visual BASIC alone does not allow you to receive or process 
  359. specific window messages.  You will need a third-party VBX or OCX control to 
  360. use this feature.
  361. Language notes for Pascal
  362. The WIN-STK works with the various Windows Pascal products published by 
  363. Borland.  However, the sample program PLAYSTK, will only compile with 
  364. Delphi.
  365.  
  366. In the reference section, you will find a prototype for each WIN-STK function 
  367. in C, Visual BASIC, and Pascal.  However, this document is somewhat C-
  368. centric.
  369.  
  370. Read on for some information which will help you comprehend the rest of the 
  371. manual.
  372.  
  373. In C, all code routines are called "functions", although in Pascal they may be 
  374. "functions" or "procedures", depending on whether they return a value.
  375.  
  376. In C, variables are declared type first, and then variable name:
  377.  
  378.         int x;
  379.  
  380. This declares a variable called x, of type integer.  Pointers are declared with a 
  381. star, like:
  382.  
  383.         int *y;
  384.  
  385. Here, y is a pointer to integer.  Some WIN-STK functions take pointer 
  386. parameters, and the sample C code in this document will use this notation.
  387.  
  388. A C struct, often called a structure, is the equivalent of a Pascal record.
  389.  
  390. C comments are either a double slash //Comment which is a comment until 
  391. the end of the line or /*Comment*/, which is equivalent to Pascal's 
  392. (*Comment*).
  393.  
  394. C expresses bitwise OR as a pipe |, bitwise AND as an ampersand &, boolean 
  395. OR as two pipes ||, and boolean AND as two ampersands &&.
  396.  
  397. In C, the ampersand & operator can also be used to take the address of a 
  398. variable.  For example:
  399.  
  400.         dws_MSongStatus(&mstat);
  401.  
  402. This call passes the address of the variable mstat to the function (which puts 
  403. the song's status into the variable).  This is equivalent to Pascal's var calling 
  404. convention.
  405.  
  406. We provide DWS.PAS, which declares all of the constants, data types, and 
  407. routines of the WIN-STK.  You will need to insert the line:
  408.  
  409. uses dws;
  410.  
  411. into your main program.  You might also want to read the source.
  412.  
  413. Pascal is not case-sensitive.  This will cause the dws_DPLAY and dws_MPLAY  
  414. record types to conflict with the corresponding function names.  Therefore, they 
  415. have a REC at the end (e.g. dws_DPLAYREC and dws_MPLAYREC).
  416.  
  417. In Pascal, the identifier message is a keyword.  Therefore in Pascal, the 
  418. message field in the dws_DPLAY record is renamed wmessage.
  419.  
  420. Another problem with Pascal and the WIN-STK is that the functions 
  421. dws_DGetInfo and dws_DSetInfo take two dws_DPLAYREC parameters 
  422. which are passed by reference (declared as var).  To tell these functions to 
  423. ignore a parameter, C and Visual BASIC programmers can pass a NIL.  The 
  424. Pascal compiler will not let you do this directly.  But there is another way of 
  425. indicating "ignore this parameter".  The dws_DPLAYREC record has a flags 
  426. field which indicates which other fields within the record you are using.  If you 
  427. set flags = 0, then the WIN-STK will behave exactly as if you had passed 
  428. NIL as the address of the record.  See the Reference section for more details.
  429.  
  430. The dws_WAV2DWD function also accepts a NIL pointer in certain cases.  
  431. However, the parameter is not a pass-by-reference variable in this function.  It's 
  432. a PBYTE, so the compiler will let you pass NIL.
  433.  
  434. This document will not further refer to these differences between Pascal and C.
  435. Installing the WIN-STK
  436. Simply copy (or unzip) the WIN-STK files into their own subdirectory tree on 
  437. your hard drive.  There are different subdirectories for C, Visual BASIC, Pascal, 
  438. the DLLs, etc.  You probably don't need all of them.
  439.  
  440. Make sure you put the files for your language where your compiler and linker 
  441. can find them.  If you need more information on this and related topics, your 
  442. compiler's manual will be far more detailed than is possible here, and will cover 
  443. your specific software environment.
  444. Installing a WIN-STK-using Program
  445. When you install your program on the user's machine, please put the WIN-STK 
  446. DLLs in the same directory as your executable(s).  This will ensure that other 
  447. programs using different versions of the WIN-STK will coexist with yours.  In 
  448. fact, this is a good practice for all DLLs in Windows.
  449. Using the WIN-STK Effectively
  450. The Tutorial and Reference sections describe, in great detail, how to use the 
  451. WIN-STK.  Here, we discuss some of the issues to think about if you want to 
  452. use the WIN-STK effectively.
  453. Stereo or Mono?
  454. The WIN-STK can output stereo or mono sound.  In most cases, you will want 
  455. to use stereo if supported by the hardware.  Elsewhere in this manual, you'll 
  456. find out how to determine if stereo is available.  You might want to use mono, 
  457. however, to save precious CPU cycles on slower machines.  Elsewhere, we 
  458. discuss other things to do to maximize performance.
  459.  
  460. So you've decided to use stereo.  But have you thought about your source 
  461. sounds?  Should you record them in stereo?
  462.  
  463. The answer depends on what you are trying to do.  If you are playing any kind 
  464. of cinematic sequence, then stereo recording is probably appropriate.
  465.  
  466. But if you want your sound to be interactive, then mono is probably a better 
  467. choice because the WIN-STK can play the left and right channels at different 
  468. volume levels.  This is called panning, and can be used to communicate a 
  469. sound's location to the user.  In fact, many 3D games use panning to localize 
  470. sound.
  471. Authoring Sound
  472. If you're authoring a long playback sequence, with little or no interactivity to it, 
  473. you may author literally anything which the hardware can play back.  The 
  474. sampling rate, sample size, and whether to use stereo will be dictated by your 
  475. creative designer, and storage considerations.
  476.  
  477. But if you're producing sound to be played simultaneously with other sounds 
  478. and be manipulated by the program, read on.
  479.  
  480. The first issue to consider is dynamic range.  In digital sound playback, there is 
  481. always a limit to how loud a sample can be.  All overflows must be clipped.  If 
  482. an occasional sample is clipped, then the user will most likely never notice it.  
  483. However, if you overload the system with many loud sounds, then the output 
  484. will sound distorted, which is usually undesirable.
  485.  
  486. Record your sounds so that they do not use a lot of dynamic range.  The goal is 
  487. to minimize the difference between the loud parts and the soft parts, making the 
  488. entire sound somewhat quiet.  Good sound editing programs offer a dynamic 
  489. range compression feature for just this purpose.
  490.  
  491. Keep the overall volume level of your sounds commensurate with how many 
  492. you expect to play at the same time.  For example, if you need to play four 
  493. sounds at a time, then each sound should use roughly ¼ of the total dynamic 
  494. range.
  495.  
  496. If you're going to use volume panning to localize sounds, then you will likely 
  497. want distant sounds to be quiet and close sounds to be loud.  In this case, record 
  498. your sound at the loudest level you'll need, and use the WIN-STK to make it 
  499. softer as it moves into the distance.
  500.  
  501. This will give you better sound quality (as well as being computationally 
  502. faster-see the next topic for details) than recording soft and raising the volume 
  503. at runtime.
  504. WIN-STK Performance
  505. 8-bit audio is less CPU intensive than 16-bit.  Using 8-bit also allows the WIN-
  506. STK to perform certain additional optimizations.
  507.  
  508. So what's the order of fastest to slowest modes?  8-bit mono is fastest, followed 
  509. by 16-bit mono, then 8-bit stereo, then 16-bit stereo.  The difference between 
  510. 16-bit mono and 8-bit stereo is slight.
  511.  
  512. There is a tradeoff between latency (the time between when your program calls 
  513. a sound function, and the time when the user hears it) and CPU usage.  A 
  514. smaller internal buffer will allow the WIN-STK to give you lower latency, but it 
  515. will need to be updated more often, thus increasing the CPU load.
  516.  
  517. Sound, unlike video, can't acceptably stall even briefly.  If the buffer is not 
  518. updated by the deadline, an audible gap or click will result.  Slower computers, 
  519. of course, will take more time before they can get around to updating the buffer.  
  520. Thus, the WIN-STK will use larger buffers on slower machines, and can get 
  521. away with smaller buffers on faster machines. 
  522.  
  523. The WIN-STK can play up to 16 digital sounds at the same time.  But you 
  524. should configure the WIN-STK to allow only for the maximum number of 
  525. voices your program will actually use.  Setting this value needlessly high will 
  526. impose CPU usage and latency penalties.
  527.  
  528. It's important to understand that the WIN-STK will convert sounds (if 
  529. necessary) to the match the output mode.  Thus, even if the output mode is 8-bit 
  530. mono, you can still play a 16-bit stereo file.
  531.  
  532. Obviously, you should author your sounds with the same sample size and 
  533. number of channels as your intended output mode.  You should only rely on the 
  534. WIN-STK's automatic format conversions if a user's sound hardware is less 
  535. capable than your target platform.  But in any event, the WIN-STK can exploit 
  536. the 8-bit optimizations if either the source sound, or the output mode, is 8-bit.
  537.  
  538. Volume change is always faster than pitch change.  Lowering the pitch is always 
  539. faster than raising it.
  540.  
  541. With 8-bit sound, lowering the volume is faster than raising the volume.  With 
  542. 16-bit sound, there is no difference in CPU usage.
  543. 16-bit vs. 32-bit DLLs
  544. The 16-bit DLL works under Windows 3.1, Windows 95, and Windows NT.  
  545. The 32-bit DLL works only under Windows 95, and NT because it makes 
  546. extensive use of multithreading.
  547. 16-Bit
  548. The 16-bit DLL is susceptible to all of the problems you normally have in 
  549. Windows 3.1.  If your application hogs the CPU for a while, then the WIN-STK 
  550. might stop playing sound until you yield again.  To get around this problem, we 
  551. provide a function (dws_Update) that you can call to keep the sound going, 
  552. even if you don't want to yield to the system.
  553.  
  554. If another application hogs the CPU (or if your user drags your window around 
  555. by the title bar), then the sound will pause.  There isn't anything that anyone can 
  556. do about it.
  557. 32-Bit
  558. The 32-bit DLL is immune to the above problems; Win32 is a superior platform 
  559. to Win16!
  560.  
  561. Be aware, however, that if you really hog the CPU within a very high-priority 
  562. thread, you can cause the sound to pause.  You probably shouldn't be doing this, 
  563. but if you must, then you must call dws_Update periodically.  High-priority 
  564. threads should only be used for fast, critical actions.
  565.  
  566. The 32-bit DLL is fully thread-safe.
  567.  
  568. The WIN-STK kernel thread runs at THREAD_PRIORITY_TIME_CRITICAL 
  569. priority.  This results in a base priority level of 15 for calling processes with a 
  570. priority class of IDLE_PRIORITY_CLASS, NORMAL_PRIORITY_CLASS, or
  571. HIGH_PRIORITY_CLASS; and a base priority level of 31 for processes with 
  572. REALTIME_PRIORITY_CLASS.  You should think long and hard before you 
  573. set your priority class to anything above HIGH_PRIORITY_CLASS!
  574. Latency vs. Smooth Playback
  575. There is a tradeoff between minimizing the latency, and playback which never 
  576. skips.  Latency is directly proportional to buffer size.  But larger buffers offer 
  577. immunity to skipping.  The WIN-STK autodetect function can do a pretty good 
  578. job calculating the buffer size on most machines, but it may not be perfect.
  579.  
  580. You might provide a slider bar for the user to make changes to the calculated 
  581. buffer size.
  582. Digitized Sound Theory
  583. This section presents a basic description of digitized sound, and some of the 
  584. theory.  You don't really need to read this, but you may find it interesting and 
  585. useful in the future.  Digitized sound on computers will certainly be used in the 
  586. future.
  587.  
  588. Digitized sound is sound that has been sampled, or quantized.  Periodically, the 
  589. analog voltage of a sound signal is measured by a special circuit called an 
  590. Analog to Digital Converter (ADC), and then stored.
  591.  
  592. Digitized sounds are discretely quantized.  This means that there is a finite set of 
  593. possible values for each sample.  It also means that there are only samples for a 
  594. finite number of instants in time.
  595.  
  596. Let's take the case of 8-bit samples.  Samples range from -128 to +127.  Any 
  597. sound softer than +/-1 is lost.  Any sound louder than +127/-128 will be clipped, 
  598. which sounds bad.  This overflow problem is compounded  if you're mixing 
  599. several sounds together, or processing the sound digitally.
  600.  
  601. Just as the range of samples is not infinite, neither is the domain.  Digitized 
  602. sounds are not contiguous in the time domain.  They're sampled at T=1 and 
  603. T=2, but not at T=1.5. There's obviously sound at every moment, even during 
  604. those in between the sample points.  But we have no record of it; a graph of 
  605. digitized sound data has a characteristic stair-step shape.  We'll look at the 
  606. problems this can cause below.
  607.  
  608. Digital signal theory asserts that every possible waveform can be represented by 
  609. the sum of a finite series of pure sine waves.  The highest frequency sine wave 
  610. in this series is no higher than the highest frequency component present in the 
  611. original wave.
  612.  
  613. The Nyquist theory of digital signal processing states that, in order to capture a 
  614. waveform containing frequencies up to F, you need to sample it at a rate of at 
  615. least 2F.
  616.  
  617. Any sampling rate, R, lower than 2F will cause the frequencies above R / 2 to be 
  618. aliased as lower frequencies.  This sounds like a metallic overtone on top of the 
  619. original sound.
  620.  
  621. To visualize this better, think of the infamous problem of drawing a diagonal 
  622. line on a low-resolution screen, or of watching a spinning propeller seem to turn 
  623. slowly backwards.  The sampling rate (resolution) of the screen is too low to 
  624. display the line.  The sampling rate of the human eye is too low to see a 15,000 
  625. RPM propeller.
  626.  
  627. When we convert digital samples back to analog, the result looks quite square 
  628. (the stair-step shape mentioned above), and not at all like the original.  This is 
  629. an immutable consequence of the process.  
  630.  
  631. The steep vertical segments in the wave are high frequencies.  Therefore, you 
  632. must send the signal through a low-pass filter to remove the extra garbage.  
  633. Sound boards all contain low-pass filters for this very reason.  In practice, a 
  634. cheap set of speakers would probably act as an effective filter for the higher 
  635. sampling rates.
  636.  
  637. Although the following doesn't really relate to computer audio, it's interesting 
  638. because it's relevant to every CD player.
  639.  
  640. Analog filters distort the sound.  The steeper the cutoff, the worse they sound.  
  641. So instead of trying to build a filter which passes everything below 20,000 Hz 
  642. and cuts everything above 20,001 Hz, CD players use oversampling.  You can 
  643. think of oversampling as "interpolation".
  644.  
  645. If you convert the sample data to the frequency domain, add extra zeroes for all 
  646. the frequencies above your actual sound data, and convert back to the time 
  647. domain, you'll have a smoother interpolation of the original sound.  More 
  648. importantly, the harmonic overtones will be at a higher frequency, and thus 
  649. easier to filter.
  650.  
  651. So the next time you buy a CD player, don't let the ignorant salesman tell you 
  652. that ".THIS player reads the disc eight times so it doesn't make as many 
  653. errors.".  You know now that oversampling is just a technique to produce 
  654. smoother output.  Even cheap CD players can read a disc without errors, or else 
  655. CD-ROM's would never work!
  656.  
  657. Tutorial
  658. This section will take you through the steps required to add sound to a C 
  659. program, starting with the barest minimum, and leading up to some more 
  660. advanced concepts and features.  Every line of code should easily convert to an 
  661. equivalent line in Visual BASIC or Pascal.
  662.  
  663. The code does not check for errors, or do any of the other things required of 
  664. robust, commercial-quality code.
  665.  
  666. Caveat: This code has not been tested or compiled!  It's good for reading 
  667. through, and to illustrate key WIN-STK implementation issues.  But, you're 
  668. better off cutting code out of PLAYSTK than attempting to use the code 
  669. presented here.
  670. The Basics
  671. The Variables
  672. void PlaySoundAndSong(void)
  673. {
  674.     FILE *fp;
  675.     BYTE *sfx;
  676.     WORD mstatus;
  677.     WORD dsize;
  678.     dws_DETECTRESULTS dres;
  679.     dws_IDEAL ideal;
  680.     dws_MPLAY mplay;
  681.     dws_DPLAY dplay;
  682.  
  683. We're going to load one sound effect from disk into memory (MIDI songs are 
  684. played directly from disk file).  sfx, a pointer, holds the address of the sound 
  685. effect buffer.  dres, and ideal are structs required for initialization.  dplay, 
  686. a struct, holds all information needed to play the sound effect; mplay, another 
  687. struct, holds information for playing the song.
  688. Loading Songs and Sounds
  689.     /* Allocate memory */
  690.     fp = fopen("sample.dwd", "rb");
  691.     fseek (fp, 0L, SEEK_END);
  692.     sfx = malloc(dsize = ftell(fp));
  693.  
  694.     /* Load the sound file */
  695.     fseek(fp, 0L, SEEK_SET);
  696.     fread(sound, dsize, 1, fp);
  697.     fclose(fp);
  698.  
  699.  
  700. This code allocates a buffer to store the sound, and then reads the sound file into 
  701. it.  SAMPLE.DWD began as SAMPLE.WAV (an 8-bit mono digitized sound, 
  702. sampled at 11kHz), and was converted by WAV2DWD.EXE.
  703. Initializing the STK
  704.     /* Run the WIN-STK's autodetect routine */
  705.     dws_DetectHardWare(&dres);
  706.  
  707.     /* Init the WIN-STK */
  708.     ideal.mustyp     = dws_muscap_MAPPER;
  709.     ideal.digtyp     = dws_digcap_11025_08_1;
  710.     ideal.dignvoices = 2;
  711.     ideal.flags      = dws_ideal_NONE;
  712.     dws_Init(&dres, &ideal);
  713.  
  714. The results of the autodetect are returned in the dres struct.
  715.  
  716. This code fails to check to see whether the WIN-STK even found a MIDI 
  717. mapper, but just assumes that it's there.  The MIDI mapper is installed on most 
  718. machines, but you can't make an assumption like that in real code!
  719.  
  720. We initialized the ideal struct to request the desired STK services.  Note how 
  721. we specified 2 voices.  This allows the WIN-STK to run at its most efficient.  
  722. Don't tell the WIN-STK to use any more voices than you need.
  723.  
  724. After the call to dws_Init, the sound hardware and the WIN-STK are set up 
  725. for business.
  726. Preparing Songs and Sounds
  727.     /* Prepare to play song */
  728.     mplay.track = "sample.mid";
  729.     mplay.count = 1;
  730.  
  731.     /* Prepare to play digitized sound */
  732.     dplay.flags = dws_dplay_SND;
  733.     dplay.snd   = sound;
  734.  
  735. The mplay struct and the dplay struct are set up prior to the calls to play 
  736. them.  The flags field in the dplay struct tells the WIN-STK which fields 
  737. have been initialized.  Since we didn't use most of the fields in the struct, they'll 
  738. take on reasonable defaults (see the Reference section for specifics).
  739. Starting Playback
  740.     /* Play song and sound */
  741.     dws_MPlay(&mplay);
  742.     dws_DPlay(&dplay);
  743.  
  744. A call to dws_MPlay starts the music, and a call to dws_DPlay begins 
  745. playback of the digitized sound effect.
  746.  
  747. The flags field in the dws_DPLAY struct was designed to allow you to use as 
  748. many or as few of the features available through the dws_DPlay function as 
  749. you want.  At a minimum, you must set dws_dplay_SND.  This indicates that 
  750. you have specified a pointer to a sound buffer.  All other fields (e.g. pitch, loop 
  751. count, etc.) are optional.  The flags mechanism also protects your program from 
  752. breaking when you upgrade to new WIN-STK releases.  If there are new 
  753. features, your program won't inadvertantly use them.
  754. Wait 'Til the Fat Lady Stops Singing
  755.     /* Wait loop */
  756.     do
  757.     {
  758.       dplay.flags = dws_dplay_SOUNDNUM;
  759.       dws_DGetInfo(&dplay, NULL);
  760.       dws_MSongStatus(&mstatus);
  761.  
  762.     } while ((dplay.soundnum) || 
  763.              (mstatus & dws_MSONGSTATUSPLAYING));
  764.  
  765. To query the sound's status, we call dws_DGetInfo, and look at the 
  766. soundnum field that it sends back to us.  When the sound is done playing, this 
  767. field is returned as 0.
  768.  
  769. Note that if you simply want to play a sound, and wait until it's done playing, 
  770. there's an easy way to do this: simply set the dws_dplay_SYNCHRONOUS 
  771. flag field.  This will cause the WIN-STK to wait until the sound is done playing 
  772. before it returns to your program.  While it's waiting, it yields to the system.
  773.  
  774. To query the song's status, we call dws_MSongStatus, with the address of a 
  775. bitfield variable.  We're interested in the dws_MSONGSTATUSPLAYING field.
  776. Shutting Down
  777.     /* Free the memory we allocated above */
  778.     free(sound);
  779.  
  780.     /* We must kill the WIN-STK */
  781.     dws_Kill();
  782. }
  783.  
  784. Normally, you would call dws_DDiscard before freeing a sound buffer, but 
  785. in this case, we know that the sound is done.
  786. The Fancy Stuff
  787. The WIN-STK does a whole lot more than what we've seen so far.  In this topic, 
  788. we'll show you how to play more than one sound at the same time (which is 
  789. called "polyphony"), how to sequence a sound after another, how to use the 
  790. WIN-STK's built-in volume and pitch control, how to change sounds once 
  791. they're playing, how to get notification that a sound is done playing, how to 
  792. play large files from disk (32-bit DLL only), and how to handle WIN-STK 
  793. errors.
  794. Polyphony
  795. The WIN-STK kernel was designed to be polyphonic from the ground up, so 
  796. you don't need any special tricks.  To play two or more sounds at the same time, 
  797. simply call dws_DPlay more than once.
  798.  
  799. The example code fragment below assumes that the WIN-STK has been 
  800. initialized.  sfx1 and sfx2 are digital sounds in memory.
  801.  
  802.     dplay.flags    = dws_dplay_SND |
  803.                      dws_dplay_PRIORITY;
  804.     dplay.snd      = sfx1;
  805.     dplay.priority = dws_NORMALPRIORITY;
  806.     dws_DPlay(&dplay);
  807.  
  808.     dplay.snd      = sfx2;
  809.     dplay.priority = dws_NORMALPRIORITY;
  810.     dws_DPlay(&dplay);
  811.  
  812. The priority field helps the WIN-STK determine which sound to drop if you 
  813. exceed the maximum number of voices (specified in the dws_IDEAL struct in 
  814. the call to dws_Init).  The issue is moot for this example, but may be a factor 
  815. in a real-world application.
  816.  
  817. Note that you can reuse the dplay struct itself; all WIN-STK functions copy 
  818. what they need from your structs before returning.
  819. Sequencing
  820. Sequencing allows you to play a sound back-to-back with another.  The first 
  821. sample of the sequenced sound plays right after the last sample of the first 
  822. sound.  The effect is that of a single sound playing seamlessly, without a pause 
  823. or even a click.
  824.  
  825. The presnd field of the dws_DPLAY struct is the key to this feature.  To 
  826. sequence sound B after sound A, then set the presnd field of sound B's 
  827. dplay struct to the soundnum of sound A (set by the call to dws_DPlay).
  828.  
  829. In the example below, assume that dplay1 and dplay2 are both structs of 
  830. type dws_DPLAY.
  831.  
  832.     dplay1.flags = dws_dplay_SND;
  833.     dplay1.snd   = sfx1;
  834.     dws_DPlay(&dplay1);
  835.  
  836.     dplay2.flags  = dws_dplay_SND | dws_dplay_PRESND;
  837.     dplay2.snd    = sfx2;
  838.     dplay2.presnd = dplay1.soundnum;
  839.     dws_DPlay(&dplay2);
  840.  
  841. This example tells the WIN-STK to wait until the first sound is complete, and 
  842. then play the second.
  843.  
  844. The WIN-STK will set the soundnum field of dplay2 to the same value as its 
  845. presnd; no matter how many sounds you sequence, they will all have the same 
  846. soundnum.
  847.  
  848. Note: if you have want to play a sequence of more than two sounds, then some 
  849. manual effort is required; the WIN-STK handles only two at a time: the one 
  850. that's playing, and the one sequenced after it.  You must wait until the first 
  851. sound is done (and hence the sequenced sound is playing) before sequencing the 
  852. third.  Use dws_DGetInfo to determine when a sound is done.
  853.  
  854. Sequencing is useful if you want to break a long sound into several pieces.  Or, 
  855. if you want to play a sound, and then "branch" to one of several sounds, 
  856. depending on some user-interaction after the first part is played (e.g. a gun fires, 
  857. continuing with either a scream or a ricochet, depending on whether the bullet 
  858. hits).
  859. Pitch and Volume Control
  860. The WIN-STK allows you to specify the left and right volume for any sound, 
  861. plus its pitch.  Actually, the WIN-STK allows you to control the playback length 
  862. of the sound, which affects the perceived pitch.  The distinction is important, 
  863. because increases in the length decrease the pitch (make it lower).
  864.  
  865.     dplay.flags = dws_dplay_SND | dws_dplay_LVOL |
  866.                   dws_dplay_RVOL | dws_dplay_PITCH;
  867.     dplay.snd   = sfx1;
  868.     dplay.lvol  = dws_IDENTITY;
  869.     dplay.rvol  = dws_IDENTITY / 2;
  870.     dplay.pitch = dws_IDENTITY * 2;
  871.     dws_DPlay(&dplay);
  872.  
  873. This example will play a sound, with the right channel softer than the left.  It 
  874. will play at a lower pitch than it was recorded at.
  875.  
  876. In a 3D game, volume control of the left and right channels can be used to 
  877. indicate the direction from which the sound is coming.
  878.  
  879. Pitch can be used to break up the monotony of a sound that's played many 
  880. times.  Just vary the pitch slightly each time you play it.
  881. Interactive Digitized Audio
  882. Now, let's take a look at what you can do with a sound once it's playing.
  883.  
  884. You could terminate it.
  885.  
  886.     dws_DDiscard(dplay.soundnum);
  887.  
  888. You could terminate it, and all other instances of the same sound file:
  889.  
  890.     dws_DDiscardAO(sfx1);
  891.  
  892. The "AO" stands for "All Occurrences".
  893.  
  894. To do anything sophisticated with a sound, you'll need dws_DGetInfo and 
  895. dws_DSetInfo.
  896. Querying a Sound's Status
  897. dws_DGetInfo can return information about a playing sound, via a 
  898. dws_DPLAY struct. You just set the flags field to indicate the fields for 
  899. which you want information.
  900.  
  901. The function knows which sound to look up based on its soundnum, so you will 
  902. need to provide that.  Remember to set the dws_dplay_SOUNDNUM bit in 
  903. flags.
  904.  
  905.     dplay.flags = dws_dplay_SOUNDNUM;
  906.     dplay.soundnum = sndnum_from_prior_call_to_dplay;
  907.     dws_DGetInfo(&dplay, NULL);
  908.  
  909. In the above example, we're asking for the soundnum field of the currently 
  910. playing sound.  dplay.soundnum will either be unchanged, or hold a 0 if the 
  911. sound is done playing.  There was no sequenced sound, so we pass NULL for 
  912. the second dplay parameter.
  913. Changing a Sound on the Fly
  914. You can change the loop count, priority, left and right volume, pitch, and 
  915. callback of a currently-playing (or sequenced) sound.
  916.  
  917. This example illustrates changing the left-channel volume of a sound:
  918.  
  919.     dplay.flags = dws_dplay_SOUNDNUM | dws_dplay_LVOL;
  920.     dplay.soundnum = sndnum_from_prior_call_to_dplay;
  921.     dplay.lvol = dws_IDENTITY / 4;
  922.     dws_DSetInfo(&dplay, NULL);
  923. Callbacks
  924. The WIN-STK can give you notification when a sound starts, ends, or aborts.  
  925. This feature relies on Windows' message queue system.  If you know your 
  926. window handle, and have a message handler (Window Procedure) installed for 
  927. the window, then this feature will work for you.
  928.  
  929. The following example illustrates how to play a sound, so that you'll be notified 
  930. when it's done.
  931.  
  932.     dplay.flags  = dws_dplay_SND | dws_dplay_CALLBACK;
  933.     dplay.snd     = sfx;
  934.     dplay.hwndmsg = hwnd;
  935.     dplay.message = WM_USER + 1;
  936.     dws_DPlay(&dplay);
  937.  
  938. The sound will play once.  The window whose handle is specified by hwnd will 
  939. receive the WM_USER + 1 message (you should, of course, create constants for 
  940. any messages you intend to use).
  941.  
  942. Your message handler can do anything it wants, including make WIN-STK 
  943. function calls.
  944.  
  945. Note: Your message handler must use the lParam parameter to determine 
  946. which event occured.  There are three possible WIN-STK callback event types: 
  947. dws_event_SOUNDCOMPLETE, dws_event_SOUNDSTARTED, and 
  948. dws_event_SOUNDABORTED.
  949. Playing Large Sounds Directly from Disk
  950. If you have a very large sound files (e.g. a 3-minute 16-bit 44kHz music track), 
  951. you might want to play it directly from the disk.
  952. Win32
  953. Under Win32 (Windows 95 and NT), you can easily do this.  The operating 
  954. system supports memory-mapped files.  The following code snippet illustrates 
  955. how to do this:
  956.  
  957. void PlayDWDFile(char *filename)
  958. {
  959.     dws_DPLAY dplay;
  960.     HANDLE hfile;
  961.     HGLOBAL hdwd;
  962.     BYTE *dwd;
  963.  
  964.     hfile = CreateFile(filename, GENERIC_READ, 0,
  965.                        NULL, OPEN_EXISTING,
  966.                        FILE_ATTRIBUTE_NORMAL, NULL);
  967.  
  968.     hdwd = CreateFileMapping(hfile, NULL, 
  969.                              PAGE_READONLY, 
  970.                              0L, 0L, "DWD");
  971.  
  972.     dwd = (BYTE*)MapViewOfFile(hdwd, FILE_MAP_READ,
  973.                                0L, 0L, 0L);
  974.  
  975.     dPlay.flags = dws_dplay_SND;
  976.     dPlay.snd   = dwd;
  977.  
  978.     dws_DPlay(&dPlay);
  979.  
  980.     /* Wait until the file is done playing */
  981.  
  982.     UnmapViewOfFile(dwd);
  983.     CloseHandle(hdwd);
  984.     CloseHandle(hfile);
  985. }
  986.  
  987. It's important to clean up by unmapping the file, and closing down the handles!
  988. Win16
  989. You can play large files from disk under Windows 3.1 also, though it's a little 
  990. bit more involved.  You read the file one manageable chunk at a time, slap a 
  991. DWD header on each chunk, and sequence the chunk after the previous chunk.
  992. Win32s
  993. The WIN-STK supports Win32s on Windows 3.1x systems.  DWSW32S.DLL is 
  994. the primary DLL for Win32s.  It provides the entire documented WIN-STK 
  995. API.  It then thunks down to DWSW16S.DLL which then makes calls into 
  996. DWSW16.DLL.  The primary difference between the 16- and the main 32-bit 
  997. DLL is multithreading.  Under Win32s, therefore, the WIN-STK uses the 16-bit 
  998. kernel to actually perform the work.
  999.  
  1000. If you're using C/C++, the code in DWSW32.LIB will automatically determine 
  1001. whether it's running under Win32s or a real Win32 environment (Windows 95 
  1002. or NT).  It will call into the correct DLL.  This library file is equivalent to a 
  1003. standard import library, though it was written in C.  Its other advantage is that it 
  1004. will not terminate your program if it can't find the DLL (it will instead report no 
  1005. sound capabilities present-true enough without the WIN-STK DLLs).
  1006.  
  1007. In Win32s systems, you must install DWSW32S.DLL, DWSW16S.DLL, and 
  1008. DWSW16.DLL.  But, you will only need to deliver only one executable-at 
  1009. least as far as the WIN-STK goes.  However, there are many substantial 
  1010. differences between different implementations of Win32s, especially so with 
  1011. Win32s.  Caveat programmer!
  1012.  
  1013. Note: Visual BASIC and Pascal/Delphi users do not have access to this C/C++ 
  1014. mechanism and must provide a separate executable file for Win32s and 
  1015. Windows 95/NT.
  1016.  
  1017. For 32-bit VB4, if you want to make an executable which runs under Win32s, 
  1018. you will need to change DWS.BAS.  In each WIN-STK function declaration, 
  1019. change "DWSW32.DLL" to "DWSW32S.DLL".  This DLL is the correct one 
  1020. for Win32s.
  1021.  
  1022. For 32-bit Delphi 2, if you want to make an executable which runs under 
  1023. Win32s, you will need to change DWS.PAS.  Change the line which contains 
  1024. DWSDLL = 'DWSW32'; to DWSDLL = 'DWSW32S'; instead.  This DLL is the 
  1025. correct one for Win32s.
  1026. Error Handling
  1027. The WIN-STK can often tell you when you're making a mistake.  All functions 
  1028. have a boolean return value.  A 1 means success.  A 0 means an error of some 
  1029. kind occurred.  In this case, you should call dws_ErrNo to determine which.
  1030.  
  1031.     if (dws_DetectHardWare(&dres) == 0)
  1032.     {
  1033.         err = dws_ErrNo();
  1034.  
  1035.         DisplayErr("during dws_DetectHardWare");
  1036.     }
  1037.  
  1038. We provide the source code to DisplayErr in C, BASIC, and Pascal.  Just 
  1039. look inside PLAYSTK.C, PLAYSTK.BAS, or PLAYSTK.PAS, respectively.
  1040.  
  1041. Reference
  1042. This section is broken down into topics for the Functions, the Errors, the Data 
  1043. Structures, the Utilities, and the File Formats.
  1044.  
  1045. Each is the definitive specification on its subject, with a minimum of verbiage.
  1046. The Functions
  1047. There are 21 functions in the WIN-STK library.
  1048.  
  1049. Unless otherwise noted, you must call dws_Init before calling any other 
  1050. WIN-STK function.
  1051.  
  1052. For each function, we give the prototypes for C, Visual BASIC, and Pascal.  We 
  1053. give a description, the parameters, related functions, and the complete list of 
  1054. errors that the function might generate.  You may assume that the list of errors is 
  1055. complete; if an error is not listed for a given function, then that function cannot 
  1056. flag that error.
  1057.  
  1058. dws_DClear
  1059. Declarations
  1060. WORD dws_DClear(void);
  1061. Declare Function dws_DClear() As Integer
  1062. function dws_DClear : WORDBOOL;
  1063. Description
  1064. This function stops all digitized sounds.
  1065. Parameters
  1066. None.
  1067. Related Functions
  1068. dws_DDiscard, dws_DDiscardAO, dws_DPlay
  1069. Errors
  1070. dws_NOTINITTED, dws_NOTSUPPORTED
  1071.  
  1072. dws_DDiscard
  1073. Declarations
  1074. WORD dws_DDiscard(WORD soundnum);
  1075. Declare Function dws_DDiscard(ByVal soundnum As
  1076.   Integer) As Integer
  1077. function dws_DDiscard(soundnum: WORD) : WORDBOOL;
  1078. Description
  1079. This function stops the specified sound.
  1080. Parameters
  1081. soundnum    number of the sound to be killed
  1082. Related Functions
  1083. dws_DClear, dws_DDiscardAO, dws_DPlay
  1084. Errors
  1085. dws_NOTINITTED, dws_NOTSUPPORTED
  1086.  
  1087. dws_DDiscardAO
  1088. Declarations
  1089. WORD dws_DDiscardAO(BYTE *snd);
  1090. Declare Function dws_DDiscardAO(snd As Long) As
  1091.   Integer
  1092. function dws_DDiscardAO(snd: PBYTE) : WORDBOOL;
  1093. Description
  1094. This function stops all occurrences of a DWD.  It's useful if you have repeatedly 
  1095. played the same sound effect, and want to stop all instances.
  1096. Parameters
  1097. snd    ptr to the DWD to stop
  1098. Related Functions
  1099. dws_DClear, dws_DDiscard, dws_DPlay
  1100. Errors
  1101. dws_NOTINITTED, dws_NOTSUPPORTED
  1102.  
  1103. dws_DetectHardWare
  1104. Declarations
  1105. WORD dws_DetectHardWare(dws_DETECTRESULTS *dr);
  1106. Declare Function dws_DetectHardWare(dr As
  1107.   dws_DETECTRESULTS) as Integer
  1108. function dws_DetectHardWare(var dr: dws_DETECTRESULTS)
  1109.   : WORDBOOL;
  1110. Description
  1111. This function determines the capabilities of the hardware and drivers, and also 
  1112. calculates the WIN-STK's internal buffer size.
  1113.  
  1114. If there is more than one audio device or device driver, the WIN-STK will 
  1115. choose the most capable: 16-bit is chosen over 8-bit, stereo over mono, and 
  1116. higher sampling rates over lower.
  1117. Notes
  1118. You may call this function only before dws_Init, or again after dws_Kill.
  1119. Parameters
  1120. dr    ptr to struct to hold the calculated information
  1121. Related Functions
  1122. dws_Init
  1123. Errors
  1124. dws_ALREADYINITTED, dws_INTERNALERROR,
  1125. dws_INVALIDPOINTER, dws_MEMORYALLOCFAILED,
  1126. dws_RESOURCEINUSE, dws_SETEVENTFAILED
  1127.  
  1128. dws_DGetInfo
  1129. Declarations
  1130. WORD dws_DGetInfo(dws_DPLAY *dp1, dws_DPLAY *dp2);
  1131. Declare Function dws_DGetInfo(dp1 As dws_DPLAY,
  1132.   dp2 As dws_DPLAY) As Integer
  1133. function dws_DGetInfo(var dp1: dws_DPLAYREC; var dp2:
  1134.   dws_DPLAYREC) : WORDBOOL;
  1135. Description
  1136. This function returns information about a playing sound, and the one sequenced 
  1137. to play after it.
  1138. Parameters
  1139. dp1    ptr to struct to hold information on currently-playing sound
  1140. dp2    the same, for sequenced sound
  1141.  
  1142. The flags field in each struct is used to specify which fields to query.  You 
  1143. must indicate which sound is of interest, by using the soundnum field in at 
  1144. least one struct.  If you initialize the soundnum field in both structs, then both 
  1145. must be the same (e.g. dp1->soundnum = dp2->soundnum).  This is 
  1146. because a sequenced sound always has the same sound ID number as the 
  1147. playing sound.
  1148.  
  1149. You may query these fields: dws_dplay_SND, dws_dplay_COUNT,
  1150. dws_dplay_PRIORITY, dws_dplay_PRESND, dws_dplay_LVOL,
  1151. dws_dplay_RVOL, dws_dplay_PITCH, or dws_dplay_CALLBACK.
  1152.  
  1153. If dws_dplay_CALLBACK is specified, then both the hwndmsg and the 
  1154. message fields are returned.
  1155. Related Functions
  1156. dws_DPlay, dws_DSetInfo
  1157. Errors
  1158. dws_D_BADDPLAY, dws_INVALIDPOINTER, dws_NOTINITTED,
  1159. dws_NOTSUPPORTED
  1160.  
  1161. dws_DGetRateFromDWD
  1162. Declarations
  1163. WORD dws_DGetRateFromDWD(BYTE *snd, WORD *rate);
  1164. Declare Function dws_DGetRateFromDWD(snd As Long,
  1165.   rate As Integer) As Integer
  1166. function dws_DGetRateFromDWD(snd: PBYTE; var rate:
  1167.   WORD) : WORDBOOL;
  1168. Description
  1169. This function returns the sampling rate of the specified DWD.
  1170. Notes
  1171. You may call this function at any time, even before dws_Init, or after 
  1172. dws_Kill.
  1173. Parameters
  1174. snd    ptr to the DWD of interest
  1175. rate    variable which will hold the returned sampling rate, in Hz
  1176. Related Functions
  1177. dws_Init, dws_WAV2DWD
  1178. Errors
  1179. dws_D_NOTADWD, dws_D_NOTSUPPORTEDVER,
  1180. dws_INVALIDPOINTER
  1181.  
  1182. dws_DPause
  1183. Declarations
  1184. WORD dws_DPause(void);
  1185. Declare Function dws_DPause() As Integer
  1186. function dws_DPause : WORDBOOL;
  1187. Description
  1188. This function pauses all digitized playback.
  1189.  
  1190. Note: all calls after the first will have no effect until dws_DUnPause is called.  
  1191. The WIN-STK does not maintain a "pause count".
  1192. Parameters
  1193. None.
  1194. Related Functions
  1195. dws_DUnPause
  1196. Errors
  1197. dws_NOTINITTED, dws_NOTSUPPORTED
  1198.  
  1199. dws_DPlay
  1200. Declarations
  1201. WORD dws_DPlay(dws_DPLAY *dplay);
  1202. Declare Function dws_DPlay(dplay As dws_DPLAY) As
  1203.   Integer
  1204. function dws_DPlay(var dplay: dws_DPLAYREC) :
  1205.   WORDBOOL;
  1206. Description
  1207. This function can play or sequence a sound.
  1208.  
  1209. "Sequencing" a sound causes it to play after another specified sound is done.
  1210.  
  1211. The dws_dplay_SYNCHRONOUS flag causes it to wait til the sound is done.
  1212. Parameters
  1213. dplay    ptr to struct specifying the sound
  1214. Note
  1215. Most of the fields in the dplay struct are optional; you must set the 
  1216. corresponding bit in the flags field to indicate which ones you're using.
  1217.  
  1218. Each field (except flags and snd) gets a reasonable default if not specified:
  1219. count    = 1
  1220. priority = dws_NORMALPRIORITY
  1221. presnd   = (none)
  1222. lvol     = dws_IDENTITY
  1223. rvol     = dws_IDENTITY
  1224. pitch    = dws_IDENTITY
  1225. hwndmsg  = (none)
  1226. message  = (none)
  1227. Related Functions
  1228. dws_DClear, dws_DDiscard, dws_DDiscardAO, dws_DGetInfo, 
  1229. dws_DSetInfo
  1230. Errors
  1231. dws_D_BADDPLAY, dws_D_NOTSUPPORTEDVER,
  1232. dws_DPlay_NOSPACEFORSOUND, dws_INVALIDPOINTER,
  1233. dws_NOTINITTED, dws_NOTSUPPORTED
  1234.  
  1235. dws_DSetInfo
  1236. Declarations
  1237. WORD dws_DSetInfo(dws_DPLAY *dp1, dws_DPLAY *dp2);
  1238. Declare Function dws_DSetInfo(dp1 As dws_DPLAY, dp2 As
  1239.   dws_DPLAY) As Integer
  1240. function dws_DSetInfo(var dp1: dws_DPLAYREC; var dp2:
  1241.   dws_DPLAYREC) : WORDBOOL;
  1242. Description
  1243. This function can change the parameters of a playing sound, and the one 
  1244. sequenced to play after it.
  1245. Parameters
  1246. dp1    ptr to struct which holds new parameters for currently playing sound
  1247. dp2    the same, for sequenced sound
  1248. Note
  1249. The flags field in each struct is used to specify which fields to modify.  You 
  1250. must indicate which sound is of interest, by using the soundnum field in at 
  1251. least one struct.  If you initialize the soundnum field in both structs, then both 
  1252. must be the same (e.g. dp1->soundnum = dp2->soundnum).  This is 
  1253. because a sequenced sound always has the same sound ID number as the 
  1254. playing sound.
  1255.  
  1256. The following parameters may be changed dws_dplay_COUNT,
  1257. dws_dplay_PRIORITY, dws_dplay_LVOL, dws_dplay_RVOL,
  1258. dws_dplay_PITCH, and dws_dplay_CALLBACK.
  1259.  
  1260. If you specify dws_dplay_CALLBACK then be sure to fill in both the 
  1261. hwndmsg and the message field.
  1262. Related Functions
  1263. dws_DGetInfo, dws_DPlay
  1264. Errors
  1265. dws_D_BADDPLAY, dws_INVALIDPOINTER, dws_NOTINITTED,
  1266. dws_NOTSUPPORTED
  1267.  
  1268. dws_DUnPause
  1269. Declarations
  1270. WORD dws_DUnPause(void);
  1271. Declare Function dws_DUnPause() As Integer
  1272. function dws_DUnPause : WORDBOOL;
  1273. Description
  1274. This function resumes digitized playback, if it was previously paused by 
  1275. dws_DPause.
  1276.  
  1277. All sounds will continue where they left off.
  1278.  
  1279. Note: all calls after the first will have no effect until dws_DPause is called 
  1280. again.  The WIN-STK does not maintain a "pause count".
  1281. Parameters
  1282. None.
  1283. Related Functions
  1284. dws_DPause
  1285. Errors
  1286. dws_NOTINITTED, dws_NOTSUPPORTED
  1287.  
  1288. dws_ErrNo
  1289. Declarations
  1290. WORD dws_ErrNo(void);
  1291. Declare Function dws_ErrNo() As Integer
  1292. function dws_ErrNo : WORD;
  1293. Description
  1294. This function returns the last error triggered by a WIN-STK function.  Call it 
  1295. after any WIN-STK function returns failure (0 or FALSE).
  1296.  
  1297. Successful WIN-STK calls do not affect the return value of dws_ErrNo.
  1298. Notes
  1299. You may call this function at any time, even before dws_Init, or after 
  1300. dws_Kill.
  1301. Parameters
  1302. None.
  1303. Related Functions
  1304. All.
  1305. Errors
  1306. None.
  1307.  
  1308. dws_Init
  1309. Declarations
  1310. WORD dws_Init(dws_DETECTRESULTS *dr, dws_IDEAL
  1311.   *ideal);
  1312. Declare Function dws_Init(dr As dws_DETECTRESULTS,
  1313.   ideal As dws_IDEAL) As Integer
  1314. function dws_Init(var dr: dws_DETECTRESULTS; var
  1315.   ideal: dws_IDEAL) : WORDBOOL;
  1316. Description
  1317. This function configures and initializes the sound device drivers and the WIN-
  1318. STK internals.  Most STK calls won't work until after this call.
  1319.  
  1320. The exceptions are dws_DetectHardWare,  dws_DGetRateFromDWD,
  1321. dws_ErrNo, and dws_WAV2DWD.
  1322. Parameters
  1323. dr    ptr to struct which holds the output from dws_DetectHardWare
  1324. ideal    ptr to struct specifying some WIN-STK mode parameters
  1325. Related Functions
  1326. dws_DetectHardWare, dws_Kill
  1327. Errors
  1328. dws_ALREADYINITTED, dws_Init_BUFTOOSMALL,
  1329. dws_INTERNALERROR, dws_INVALIDPOINTER,
  1330. dws_MEMORYALLOCFAILED, dws_NOTSUPPORTED,
  1331. dws_RESOURCEINUSE, dws_SETEVENTFAILED
  1332.  
  1333. dws_Kill
  1334. Declarations
  1335. WORD dws_Kill(void);
  1336. Declare Function dws_Kill() As Integer
  1337. function dws_Kill : WORDBOOL;
  1338. Description
  1339. This function kills the WIN-STK.
  1340.  
  1341. If you have successfully called dws_Init, then you must call this function 
  1342. before your program terminates.
  1343. Parameters
  1344. None.
  1345. Related Functions
  1346. dws_Init
  1347. Errors
  1348. dws_NOTINITTED
  1349.  
  1350. dws_MClear
  1351. Declarations
  1352. WORD dws_MClear(void);
  1353. Declare Function dws_MClear() As Integer
  1354. function dws_MClear : WORDBOOL;
  1355. Description
  1356. This function kills the music playback.
  1357. Parameters
  1358. None.
  1359. Related Functions
  1360. dws_MPlay
  1361. Errors
  1362. dws_INTERNALERROR, dws_NOTINITTED, dws_NOTSUPPORTED
  1363.  
  1364. dws_MPause
  1365. Declarations
  1366. WORD dws_MPause(void);
  1367. Declare Function dws_MPause() As Integer
  1368. function dws_MPause : WORDBOOL;
  1369. Description
  1370. This function pauses music playback.
  1371.  
  1372. Note: all calls after the first will have no effect until dws_MUnPause is called.  
  1373. The WIN-STK does not maintain a "pause count".
  1374. Parameters
  1375. None.
  1376. Related Functions
  1377. dws_MUnPause
  1378. Errors
  1379. dws_NOTSUPPORTED, dws_NOTINITTED
  1380.  
  1381. dws_MPlay
  1382. Declarations
  1383. WORD dws_MPlay(dws_MPLAY *mplay);
  1384. Declare Function dws_MPlay(mplay As dws_MPlay) As
  1385.   Integer
  1386. function dws_MPlay(var mplay: dws_MPLAYREC) :
  1387.   WORDBOOL;
  1388. Description
  1389. This function starts playing a MIDI song.  For WIN-STK version 1, the MIDI 
  1390. song must be played from disk.  Version 2 will play from a memory buffer.
  1391. Notes
  1392. When specifying the MIDI filename, be sure to use the full pathname.
  1393. Parameters
  1394. mplay    ptr to struct specifying the song
  1395. Related Functions
  1396. dws_MPause, dws_MSongStatus
  1397. Errors
  1398. dws_INTERNALERROR, dws_INVALIDPOINTER, dws_NOTINITTED,
  1399. dws_NOTSUPPORTED, dws_M_BADMPLAY
  1400.  
  1401. dws_MSongStatus
  1402. Declarations
  1403. WORD dws_MSongStatus(WORD *result);
  1404. Declare Function dws_MSongStatus(result As Integer) As
  1405.   Integer
  1406. function dws_MSongStatus(var result: WORD) : WORDBOOL;
  1407. Description
  1408. This function returns the status of the music playback engine.
  1409. Parameters
  1410. result    ptr to a variable to hold the returned status:
  1411.  
  1412. 0                         //no song loaded
  1413. dws_MSONGSTATUSPLAYING    //song playing
  1414. dws_MSONGSTATUSPAUSED     //no song loaded, STK paused
  1415. dws_MSONGSTATUSPLAYING | dws_MSONGSTATUSPAUSED //Song
  1416.     loaded but paused
  1417. Related Functions
  1418. dws_MPause, dws_MPlay, dws_MUnPause
  1419. Errors
  1420. dws_INVALIDPOINTER, dws_NOTINITTED, dws_NOTSUPPORTED
  1421.  
  1422. dws_MUnPause
  1423. Declarations
  1424. WORD dws_MUnPause(void);
  1425. Declare Function dws_MUnPause() As Integer
  1426. function dws_MUnPause : WORDBOOL;
  1427. Description
  1428. This function resumes music playback, if it was previously paused by 
  1429. dws_MPause.
  1430.  
  1431. The music will continue where it left off.
  1432.  
  1433. Note: all calls after the first will have no effect until dws_MPause is called 
  1434. again.  The WIN-STK does not maintain a "pause count".
  1435. Parameters
  1436. None.
  1437. Related Functions
  1438. dws_MPause
  1439. Errors
  1440. dws_NOTINITTED, dws_NOTSUPPORTED
  1441.  
  1442. dws_Update
  1443. Declarations
  1444. WORD dws_Update(void);
  1445. Declare Function dws_Update() As Integer
  1446. function dws_Update : WORDBOOL;
  1447. Description
  1448. This function keeps the digitized sound going, even if your application is 
  1449. hogging the CPU.  Under normal circumstances, calling this function shouldn't 
  1450. be necessary with the 32-bit WIN-STK DLL.  In a 16-bit program, on the other 
  1451. hand, you may need to call dws_Update to prevent sound skipping, unless 
  1452. you are scrupulous about yielding time to the system frequently.  We 
  1453. recommend an interval of 55ms (18.2 Hz).
  1454. Notes
  1455. The Windows API timeSetEvent can be used to give you a callback during 
  1456. each hardware timer interrupt.  During such callbacks, most Windows API calls 
  1457. are off-limits; Windows is not reentrant.  dws_Update makes function calls 
  1458. which are in this category.  Calling it from an interrupt-time callback will crash 
  1459. Windows!
  1460. Parameters
  1461. None.
  1462. Related Functions
  1463. None.
  1464. Errors
  1465. dws_NOTINITTED
  1466.  
  1467. dws_WAV2DWD
  1468. Declarations
  1469. WORD dws_WAV2DWD(BYTE *wave, DWORD *len, BYTE *dwd);
  1470. Declare Function dws_WAV2DWD(wave As Long, len As
  1471.   Long, dwd As Long) As Integer
  1472. function dws_WAV2DWD(wave: PBYTE; var len: DWORD; snd:
  1473.   PBYTE) : WORDBOOL;
  1474. Description
  1475. This function can convert a WAV-format buffer to DWD-format.  DWD is the 
  1476. digitized sound format used by DiamondWare's Sound ToolKit.
  1477. Notes
  1478. There are two usages of this function.  The first returns the buffer length 
  1479. required to hold the DWD.  The second converts the WAV to DWD format.
  1480. Notes
  1481. You may call this function at any time, even before dws_Init, or after 
  1482. dws_Kill.
  1483. Parameters
  1484. Usage 1
  1485. wave    ptr to buffer containing a valid WAV file
  1486. len    length of the WAV buffer
  1487. dwd    NULL
  1488. Usage 2
  1489. wave    ptr to WAV buffer
  1490. len    length of the WAV (input), size of DWD (output)
  1491. dwd    ptr to a buffer to hold the DWD output
  1492. Related Functions
  1493. dws_DGetRateFromDWD, dws_DPlay
  1494. Errors
  1495. dws_INTERNALERROR, dws_INVALIDPOINTER,
  1496. dws_WAV2DWD_NOTAWAVE, dws_WAV2DWD_UNSUPPORTEDFORMAT
  1497.  
  1498. dws_XDig
  1499. Declarations
  1500. WORD dws_XDig(WORD lvolume, WORD rvolume);
  1501. Declare Function dws_XDig(ByVal lvolume As Integer,
  1502.   ByVal rvolume As Integer) As Integer
  1503. function dws_XDig(lvolume, rvolume: WORD) : WORDBOOL;
  1504. Description
  1505. This function allows you to control the overall volume for digitized sound 
  1506. output.
  1507. Parameters
  1508. lvolume    left volume, 0=off, dws_IDENTITY=normal, 65535=MAX
  1509. rvolume    same, for right channel
  1510. Related Functions
  1511. dws_DPlay
  1512. Errors
  1513. dws_NOTINITTED, dws_NOTSUPPORTED
  1514.  
  1515. The Errors
  1516. There are 16 errors (plus one non-error) which may be generated by a WIN-
  1517. STK function.
  1518.  
  1519. 0 dws_EZERO
  1520. This is a non-error.  dws_ErrNo will return this if you call it before any WIN-
  1521. STK function triggers an error.
  1522.  
  1523. 1 dws_NOTINITTED
  1524. The STK was not initialized when you called an STK function.
  1525.  
  1526. 2 dws_ALREADYINITTED
  1527. This call cannot be made after the STK is initialized.
  1528.  
  1529. 3 dws_NOTSUPPORTED
  1530. The installed hardware, or current WIN-STK mode doesn't support the 
  1531. requested feature (music or sound).
  1532.  
  1533. 4 dws_INTERNALERROR
  1534. The STK encountered an invalid internal state.  Please report this to  
  1535. DiamondWare.
  1536.  
  1537. 5 dws_INVALIDPOINTER
  1538. You passed an invalid pointer to a function.  Under Win32, the WIN-STK can 
  1539. sometimes catch this type of problem and trigger an error.
  1540.  
  1541. 6 dws_RESOURCEINUSE
  1542. The WIN-STK tried to open a device driver, but it was already opened by 
  1543. another program.
  1544.  
  1545. 7 dws_MEMORYALLOCFAILED
  1546. The WIN-STK tried to allocate some memory, but was denied.
  1547.  
  1548. 8 dws_SETEVENTFAILED
  1549. The WIN-STK tried to set an event semaphore, but was denied.
  1550.  
  1551. 9 dws_BUSY
  1552. The WIN-STK is currently processing something; please try your call again 
  1553. later.  This error can only occur in 16-bit programs, and if you're calling the 
  1554. WIN-STK from an interrupt handler or equivalent.  The error cannot occur in 
  1555. 32-bit programs, because the WIN-STK is thread-safe.
  1556.  
  1557.  
  1558. 101 dws_Init_BUFTOOSMALL
  1559. You tried to set the buffer size in the dws_IDEAL struct to something which 
  1560. was obviously too small.
  1561.  
  1562. 201 dws_D_NOTADWD
  1563. The DWD buffer you passed did not contain a DWD file.
  1564.  
  1565. 202 dws_D_NOTSUPPORTEDVER
  1566. The DWD buffer you passed contained an unknown or unsupported version of 
  1567. DWD file.
  1568.  
  1569. 203 dws_D_BADDPLAY
  1570. You set up a dws_DPLAY struct which was not valid for the function called.
  1571.  
  1572. Note: dws_DGetInfo and dws_DSetInfo require the soundnum field to 
  1573. specify the sound.
  1574.  
  1575. 251 dws_DPlay_NOSPACEFORSOUND
  1576. This is more of a warning than an error.  It's telling you that there are no sound 
  1577. slots left, and that the priority of your new sound was too low to displace any 
  1578. playing sound.
  1579.  
  1580. 301 dws_WAV2DWD_NOTAWAVE
  1581. The WAV buffer you passed did not contain a WAV file.
  1582.  
  1583. 302 dws_WAV2DWD_UNSUPPORTEDFORMAT
  1584. The WAV buffer you passed contained an unknown or unsupported version of 
  1585. WAV file.
  1586.  
  1587. 401 dws_M_BADMPLAY
  1588. You set up a dws_MPLAY struct which was not valid for the function called.
  1589.  
  1590.  
  1591. The Data Structures
  1592. There are 4 structure types provided by the WIN-STK.  Their formats and 
  1593. specifications are detailed here.
  1594. dws_DETECTRESULTS
  1595. This struct is filled in by dws_DetectHardWare.  The digbfr field is user-
  1596. writable, but use caution.
  1597.  
  1598. Note: information is stored in the reserved field.  If you're writing this struct 
  1599. out to a file, make sure to write out the entire contents.  Failure to do this may 
  1600. result in unpredictable behavior!
  1601.  
  1602. Name     Size    Description
  1603. muscaps  4      *bitwise OR of available music devices
  1604. digcaps  4      +bitwise OR of available WAV modes
  1605. digbfr   4       buffer size calculated by autodetect
  1606. reserved 20      undocumented
  1607.  
  1608. *The music devices are dws_muscap_MIDIPORT (external MIDI port, MPU-
  1609. 401 adapter or compatible, wavetable board, etc.), dws_muscap_SYNTH (a 
  1610. generic internal synthesizer), dws_muscap_SQSYNTH (a square-wave synth), 
  1611. dws_muscap_FMSYNTH (FM synthesizer), and dws_muscap_MAPPER (the 
  1612. MIDI mapper).  If there is no MIDI capability installed in the machine, then the 
  1613. muscaps field will be set to dws_muscap_NONE.
  1614.  
  1615. +The WAV modes are dws_digcap_11025_08_1,
  1616. dws_digcap_11025_08_2, dws_digcap_11025_16_1,
  1617. dws_digcap_11025_16_2, dws_digcap_22050_08_1,
  1618. dws_digcap_22050_08_2, dws_digcap_22050_16_1,
  1619. dws_digcap_22050_16_2, dws_digcap_44100_08_1,
  1620. dws_digcap_44100_08_2, dws_digcap_44100_16_1, and
  1621. dws_digcap_44100_16_2.  If there is no WAV capability in the machine, 
  1622. then the digcaps field will be set to dws_digcap_NONE.
  1623.  
  1624. The format of each constant is dws_digcap_<sampling rate in Hz>_<bits per 
  1625. sample>_<number of channels> (e.g. dws_digcap_22050_08_2 for 22kHz 
  1626. 8-bit stereo).
  1627. dws_IDEAL
  1628. This struct allows you to control the mode and features that the WIN-STK will 
  1629. set up when it initializes.
  1630.  
  1631. Name       Size    Description
  1632. flags      4      *bitwise OR of options
  1633. mustyp     4       preferred MIDI device
  1634. digtyp     4       preferred WAV output mode
  1635. dignvoices 2       max digitized voices to mix
  1636. reserved   18      undocumented
  1637.  
  1638. *The possible flags are dws_ideal_SWAPLR (if the left and right channels 
  1639. are reversed by the hardware, the WIN-STK can swap them to compensate), 
  1640. dws_ideal_DISABLEPITCH (for extra speed, disable pitch changing on 
  1641. slow machines with one simple flag), dws_ideal_DISABLEVOLUME (for 
  1642. even more speed, disable volume changing), and dws_ideal_MAXSPEED (a 
  1643. shortcut to disable the pitch and volume change feature).  Specify 
  1644. dws_ideal_NONE if you don't want any of these options.
  1645. dws_DPLAY
  1646. This struct is used for playing or sequencing a digitized sound (the dws_DPlay 
  1647. function).  It's also used for querying a playing or sequenced sound (the 
  1648. dws_DGetInfo function) and reprogramming a playing or sequenced sound 
  1649. (the dws_DSetInfo function).
  1650.  
  1651. Name       Size    Description
  1652. flags      4      *bitfield specifying fields used
  1653. snd        4       pointer to DWD buffer
  1654. count      2       number of times to play; 0=infinite
  1655. priority   2      +higher numbers = higher priorities
  1656. presnd     2       soundnum of sound to sequence after
  1657. soundnum   2       number assigned to this sound
  1658. lvol       2       left volume, 0-dws_IDENTITY-65535
  1659. rvol       2       the same, for the right channel
  1660. pitch      2      #playback length
  1661. dummy      2       pads next field to dword boundary
  1662. hwndmsg   ^4      =handle of window to send msgs to
  1663. message   ^4       message ID to send
  1664. reserved  ^18      undocumented
  1665.  
  1666. *There is a bitfield flag corresponding to each field in this struct, except that 
  1667. hwndmsg and message must be specified as a pair, and so get only one flag.  
  1668. Additionally, some flags directly control functional behavior, and so do not 
  1669. correspond to any field in the struct.  The flags are dws_dplay_SND, 
  1670. dws_dplay_COUNT, dws_dplay_PRIORITY, dws_dplay_PRESND,
  1671. dws_dplay_SOUNDNUM, dws_dplay_LVOL, dws_dplay_RVOL,
  1672. dws_dplay_PITCH, dws_dplay_CALLBACK,
  1673. dws_dplay_SYNCHRONOUS, dws_dplay_FIRSTSAMPLE,
  1674. dws_dplay_CURSAMPLE, and dws_dplay_LASTSAMPLE.  For each field 
  1675. in the struct you use, set the corresponding bit in flags.
  1676.  
  1677. +If the program tries to play more sounds than specified in the dws_IDEAL 
  1678. struct passed to dws_Init, then the lowest priority sound will be dropped.
  1679.  
  1680. #The pitch field actually controls the playback length.  In other words, lower 
  1681. values mean higher frequencies, and higher values mean lower (and slower) 
  1682. playback.  As with volume change, dws_IDENTITY means no change in 
  1683. volume.
  1684.  
  1685. ^Sizes are given for the 32-bit DLL.  For the 16-bit DLL, hwndmsg and 
  1686. message are both 2 bytes.  reserved is 22 bytes.
  1687.  
  1688. =When the WIN-STK send you a window message, the wParam parameter 
  1689. holds the soundnum, and lParam holds dws_event_SOUNDCOMPLETE, 
  1690. dws_event_SOUNDSTARTED, or dws_event_SOUNDABORTED.
  1691. dws_MPLAY
  1692. This struct is used for playing a MIDI song by the dws_MPlay function.
  1693.  
  1694. Name       Size    Description
  1695. track      4       0-terminated filename of MIDI song
  1696. count      2       number of times to play; 0=infinite
  1697. reserved   10      undocumented
  1698.  
  1699. The Utilities
  1700. We provide two utilities, PLAYSTK (with source in C, Visual BASIC, and 
  1701. Pascal) and WAV2DWD.  Both include 16- and 32-bit versions.
  1702. PLAYSTK
  1703. PLAYSTK is provided mostly as a source-code example of how to use the 
  1704. WIN-STK.  It's also useful as a test to see if the machine is working.  It can play 
  1705. several digitized sounds (.WAV or .DWD format) plus a song (.MID format) at 
  1706. the same time.
  1707.  
  1708. It's implemented as a dialog box.  On the right side are sliders for volume and 
  1709. pitch control.  These affect all new sounds played, and they'll also change the 
  1710. most recent currently playing sound.  There is a check box to reverse the left 
  1711. and right channels.  And there are three radio buttons to control sampling rate.  
  1712. The program is hard-wired for 8-bit stereo output.
  1713.  
  1714. The New button will bring up a dialog box which allows you to open any 
  1715. .WAV, .DWD, or .MID file.
  1716.  
  1717. The Play button will start whichever sound or song is selected in the listbox.  
  1718. Double-clicking on a listbox item will also play it.
  1719.  
  1720. The Stop button will stop all noise.
  1721.  
  1722. The Remove button will delete the selected listbox item.
  1723.  
  1724. Operation should be straightforward and intuitive.  The source code shows you 
  1725. many WIN-STK programming techniques.
  1726. WAV2DWD
  1727. This program is provided to make batch conversion of a large number of WAV 
  1728. files easy.  The WIN-STK can convert WAV buffers to DWD at runtime.  But if 
  1729. you know what files you need in advance, then converting them off-line is the 
  1730. best way to go.
  1731.  
  1732. This program is implemented as a dialog box.
  1733.  
  1734. There are three windows on the left side to control the source (WAV) file 
  1735. selections.  They are drive, directory, and file listboxes.  The three windows on 
  1736. the right side control drive and directory for the output (DWD) plus show 
  1737. (without any user control) the list of DWD files in the output directory.
  1738.  
  1739. Once you've set up your source and destination directories, select one or more 
  1740. WAV files to convert.  Hit the Convert button, and DWD files quickly appear.
  1741.  
  1742. 8-bit mono WAVs convert to DWDs which are also suitable for use with the 
  1743. DOS-STK.
  1744.  
  1745. The File Formats
  1746. WIN-STK version 1 uses one file format specified by DiamondWare.  It's called 
  1747. DWD (DiamondWare Digitized).
  1748.  
  1749. The specification is provided here in the hope that it may be useful to you.  
  1750. Permission is hereby granted to use this specification in the creation of any 
  1751. software.  The specification itself is, of course, protected by United States law 
  1752. and international treaty provisions.
  1753. DWD Header
  1754. Byte #  Description
  1755. 00-22   "DiamondWare Digitized\n\0"
  1756. 23      1A (EOF to abort printing of file)
  1757. 24      Major version number
  1758. 25      Minor version number
  1759. 26-29   Unique sound ID (checksum XOR timestamp)
  1760. 30      Reserved
  1761. 31      Compression type (0=none)
  1762. 32-33   Sampling rate (in Hz)
  1763. 34      Number of channels (1=mono, 2=stereo)
  1764. 35      Number of bits per sample (8, 16)
  1765. 36-37   Absolute value of largest sample in file
  1766. 38-41   length of data section (in bytes)
  1767. 42-45   # samples (16-bit stereo is 4 bytes/sample)
  1768. 46-49   Offset of data from start of file (in bytes)
  1769. 50-53   Reserved for future expansion (markers)
  1770. 54-55   Padding
  1771. ??-??   Future expansion (heed the 2 offsets, above!)
  1772. About DWD Version Numbers
  1773. The DWD specification v1.0, finalized in 1994, did not need modification to 
  1774. support the WIN-STK.  However, due to a slight oversight, the DOS-STK does 
  1775. not reject DWD files which are stereo and/or 16-bit, even though it cannot 
  1776. correctly play them (there was no software which could generate such files back 
  1777. then).  We can't recall that product, so we are incrementing the version # of the 
  1778. file.
  1779.  
  1780. 8-bit mono DWD files with no compression should be marked as version 1.0.  
  1781. The DOS- or WIN-STK can correctly play these files.  If a DWD file contains 
  1782. two (or more) channels, 16 (or more) bits per sample, or compression, then it 
  1783. must be marked as version 1.1, which will be rejected by the DOS-STK.  Our 
  1784. WAV2DWD utility generates files according to this version numbering scheme.
  1785.  
  1786. The WIN-STK will attempt to play any file of version 1.x (unlike the DOS-
  1787. STK).  Any future enhancements to the file format which break backwards 
  1788. compatibility will jump to 2.0 or higher for this reason.
  1789. Sample Format
  1790. Samples are stored as signed data.  That is, each 8-bit sample ranges from -128 
  1791. to +127.  16-bit samples range from -32768 to +32767.
  1792.  
  1793. Monophonic files are stored in order, from sample 0 to sample N.
  1794.  
  1795. Stereophonic files are stored in order, with the left channel of each sample 
  1796. preceding the right.
  1797.  
  1798. DWD File Format Clarification, September 8, 1996
  1799. Starting at byte 56, and continuing to the offset of the sound data (which is
  1800. specified in the DWORD at bytes 46-49), there is room for additional text
  1801. information fields (e.g. title, copyright, comments, etc.)
  1802.  
  1803. So long as the offset-to-data field is correct, all code written to play or
  1804. parse DWD files (going back to the DOS-STK v1.0) will continue to work
  1805. correctly.
  1806.  
  1807. Each text string in this new section must be NULL-terminated, and the entire
  1808. section should itself be NULL-terminated.  Also, just like the environment-
  1809. variable model from which this borrows, each string will be of the format:
  1810. <name>=value.
  1811.  
  1812. In all fields which might contain multiple names (e.g. keywords, editor), we
  1813. recommend that you separate each value with a semicolon and a space (e.g. Bob
  1814. Miller; John Smith).  It will help, with such digital editors as CoolEdit.
  1815. For the same reason, do not use any newlines.
  1816.  
  1817. Each of the following fields is optional, and may occur in any order:
  1818.  
  1819. TITLE
  1820.   This brief name should describe the digital sound, but be short enough for
  1821.   display in a listbox.
  1822. ORGARTIST
  1823.   The name of the author of the original sound, before digital editing.
  1824. GENRE
  1825.   Metal, jazz, classical, instrument, sound effect, etc.
  1826. KEYWORDS
  1827.   For searching.
  1828. DIGSRC
  1829.   Describe the source format (e.g. AAD CD), digitizer used (e.g. SB 16), etc.
  1830. ORGMEDIUM
  1831.   Voice, orchestra, industral site, etc.
  1832. EDITOR
  1833.   The name(s) of the editor(s) who worked on the file, or edited it in any way.
  1834.   Give credit where credit is due.
  1835. DIGITIZER
  1836.   The name of the person who digitized the file.
  1837. COMMENT
  1838.   Please end each sentence with a period.
  1839. SUBJECT
  1840.   Describes the subject matter recorded.
  1841. SRC
  1842.   The source of the sound: a record label, studio engineer, or whomever
  1843.   actually recorded it.
  1844. COPYRIGHT
  1845.   Example: Copyright 1996, DiamondWare, Ltd.  All Rights Reserved.
  1846. SOFTWARE
  1847.   The program used to edit this file.
  1848. CREATEDATE
  1849.   The date of the original recording.  Use yyyy-mm-dd format (e.g. 1996-09-08).
  1850.  
  1851. Appendix
  1852. Changes from the Sound ToolKit for DOS
  1853. If you have used DiamondWare's Sound ToolKit for DOS, you may wish to 
  1854. skim most of the manual and study this section.
  1855.  
  1856. In all cases we have attempted to preserve the same API and behavior as in the 
  1857. DOS version.  Some changes, many bona fide enhancements, were required or 
  1858. made possible by the move to Windows.
  1859.  
  1860. We'll go over the changes to the data structures, functions, behavior, errors, 
  1861. samples, and utility software.
  1862. Data Structures
  1863. Note: we changed all occurrences of  byte, word, and dword to BYTE, 
  1864. WORD, and DWORD, to conform to the Windows convention.
  1865. Pascal Note
  1866. The DOS-STK used explicit pointer syntax.  The WIN-STK now uses the var 
  1867. keyword.
  1868. dws_DETECTOVERRIDES
  1869. In Windows, the sound driver deals with the port, DMA, and IRQ settings, so 
  1870. the STK doesn't need to try to autodetect them.  This struct was originally 
  1871. provided to override the autodetect, and has been completely eliminated in the 
  1872. WIN-STK.
  1873. dws_DETECTRESULTS
  1874. Forget everything you learned about this structure under DOS.  Its purpose is 
  1875. still the same: to store the results of the autodetect.  But under Windows, we're 
  1876. detecting buffer size, driver and hardware capabilities, not hardware settings.
  1877.  
  1878. You might want to read about this structure in the Reference section.
  1879. dws_IDEAL
  1880. digrate has been merged into digtyp, which is now a bitfield.  Read the 
  1881. section on the dws_IDEAL struct for details on how this works.
  1882.  
  1883. In Windows, there is often a choice of music output devices (with different 
  1884. levels of sound quality).  The muscaps field in the dws_DETECTRESULTS 
  1885. struct tells you which drivers are installed.  The mustyp field in the 
  1886. dws_IDEAL struct allows you to specify which one to use.
  1887.  
  1888. There is now a flags field, which allows you to disable volume and/or pitch 
  1889. changing support (for slower machines).  It also allows you to specify that the 
  1890. left and right channels should be swapped (to compensate for wiring problems 
  1891. downstream).
  1892. dws_DPLAY
  1893. This structure has been greatly expanded, due to the integration of volume/pitch 
  1894. change functionality into the kernel, and the new support for stereo.
  1895.  
  1896. You should set the first field, flags, to indicate which of the rest of the fields 
  1897. you're using.  In most cases, unused fields will assume reasonable defaults--see 
  1898. the complete discussion in the Reference section for details.
  1899.  
  1900. snd, count, priority, presnd, and soundnum work as they did in the 
  1901. DOS version.
  1902.  
  1903. We added lvol and rvol to control the left and right volume of the sound.
  1904.  
  1905. Note:  Both mono and stereo source sounds will play in stereo, so long as the 
  1906. output mode is stereo.
  1907.  
  1908. pitch controls the playback rate of the sound.  More specifically, it controls 
  1909. the length of the sound during playback.  Thus higher numbers correspond to 
  1910. slower and lower sounds, and lower numbers correspond to faster and higher 
  1911. sounds.
  1912.  
  1913. For normal playback, use dws_IDENTITY for lvol, rvol, and pitch.
  1914.  
  1915. The WIN-STK can notify you when a sound is done playing.  For this feature, 
  1916. use the last two fields: hwndmsg and message.  The WIN-STK will send 
  1917. message ID message to the window whose handle is hwndmsg.  In this 
  1918. message, the wParam parameter holds the soundnum, and the lParam 
  1919. parameter holds dws_event_SOUNDCOMPLETE (future versions will support 
  1920. more types of events).
  1921. dws_MPLAY
  1922. The track field is now a NULL-terminated string holding the filename of the 
  1923. MIDI song to play (future versions will again play music from memory buffers).
  1924. Functions
  1925. We removed some functions, added a few new ones, and changed one.
  1926. Removed
  1927. dws_DGetRate
  1928. dws_DSetRate
  1929. dws_DSoundStatus
  1930. dws_XMaster
  1931. dws_XMusic
  1932. dwt_*
  1933.  
  1934. The playback rate cannot be changed while the STK is running under Windows.  
  1935. However, the built-in DSP can compensate for the odd sound recorded at a 
  1936. different sampling rate (there will be some sound quality loss, however).
  1937.  
  1938. dws_DSoundStatus has been replaced with dws_DGetInfo, which is 
  1939. much more powerful.  This function pairs well with dws_DSetInfo.
  1940.  
  1941. In Windows, the user can change the mixer volumes at will using the control 
  1942. panel.  Therefore, it's unnecessary (and counter to the Windows paradigm) for 
  1943. an application to gratuitously change them.  Thus, we've eliminated 
  1944. dws_XMaster and dws_XMusic.  Below, read what we've done with 
  1945. dws_XDig.
  1946.  
  1947. Because implementing a timer like the DWT is trivial in Windows, and because 
  1948. the WIN-STK doesn't require you to call dws_Update frequently and 
  1949. periodically (see below), we're no longer providing the DWT.
  1950. Added
  1951. dws_DGetInfo
  1952. dws_DSetInfo
  1953. dws_WAV2DWD
  1954.  
  1955. dws_DGetInfo will return you a full dws_DPLAY structure full of 
  1956. information about a playing or sequenced sound.  You can change most of the 
  1957. fields, and then call dws_DSetInfo.  See the Reference section for details.
  1958.  
  1959. dws_WAV2DWD allows you to convert WAV files to DWD format at runtime.
  1960. Changed
  1961. dws_Update
  1962. dws_XDig
  1963.  
  1964. In the DOS-STK, dws_Update kept the music playing; if you didn't call it, 
  1965. you didn't get music.  We provided the optional DWT module to take care of 
  1966. this, or you could call it from your own hardware time handler.  All of this stuff 
  1967. is unnecessary in Windows.
  1968.  
  1969. But Windows (version 3.x) causes other problems.  Each application runs until it 
  1970. voluntarily yields time to the system and other applications.  "Normal" 
  1971. applications are supposed to play nicely, and yield frequently.  If an application 
  1972. hogs the system, all other apps (and the Windows GUI) freeze until the hog 
  1973. yields.  This is bad enough (though often tolerated) with productivity 
  1974. applications.  But it's totally unacceptable for sound to stop and then resume 
  1975. playing a quarter-second later.  The discontinuity jars the listener.
  1976.  
  1977. Games and multimedia applications can generally assume that they're not 
  1978. sharing the system with email, word processors, spreadsheets, etc.  But they do 
  1979. often spend significant time in tight loops, and sometimes it's quite inconvenient 
  1980. to yield time to the system.
  1981.  
  1982. If your Windows 3.x application needs to hog the system for a while, call 
  1983. dws_Update periodically; we recommend an interval of 55ms (18.2 times per 
  1984. second).  This will keep the sound rolling under 3.x (the only way to stop it is to 
  1985. drag your application by the title bar).  Under 95/NT, the 32-bit version of the 
  1986. WIN-STK is multithreaded, though the function is fully enabled, and works as it 
  1987. does under 16 bits.
  1988.  
  1989. dws_XDig no longer controls the hardware mixer.  Instead, it controls our 
  1990. internal software mixer.  Thus, it makes it easy to quickly lower or raise (subject 
  1991. to clipping distortion) the overall digitized volume level.  dws_XMusic (and 
  1992. dws_XMaster) will return with WIN-STK v2, which will provide much 
  1993. greater control over MIDI music.
  1994.  
  1995. dws_XDig now takes two parameters, to support stereo.  And these parameters 
  1996. are 0 to 256 (dws_IDENTITY) to 65535, rather than 0-255 in the DOS version.  
  1997. The ability to make digitized playback louder via dws_XDig is new for the 
  1998. WIN-STK.
  1999. Behavior
  2000. Some changes in behavior are noted above in the discussions of the various data 
  2001. structures and functions.  Below, in no particular order, are some other changes 
  2002. of which you should be aware.
  2003.  
  2004. In the DOS-STK, the digitized buffer size was a purely internal issue.  Our 
  2005. research and testing determined the buffer size.  We compiled it into the STK, 
  2006. and it just worked.  Unfortunately, under Windows, the buffer size must change 
  2007. from system to system.  Why?  Because larger buffers are less susceptible to 
  2008. skipping, but smaller buffers provide lower latency (the time between the call to 
  2009. dws_DPlay and when the user actually hears the sound).  Slower machines 
  2010. therefore require larger buffers.  Buffer size determination is a non-trivial 
  2011. calculation, which is performed during dws_DetectHardWare.  You might 
  2012. provide your user a slider bar with some amount of control over buffer size, to 
  2013. optimize on his machine the tradeoff between latency and skipless playback. 
  2014.  
  2015. After the call to dws_DetectHardWare, you can change digbfr slightly 
  2016. (go easy!) according to the user's input.  Of course, most of the time, the 
  2017. autodetect routine will do its job properly, and you won't need to monkey with 
  2018. this setting.  Unless there's a problem with skipping, leave it alone.
  2019.  
  2020. The DOS version dropped low-priority sounds out when the dynamic range of 
  2021. the hardware would otherwise be exceeded.  The WIN-STK can clip sounds on 
  2022. a sample-by-sample basis.  Each sound must still have a priority so that if the 
  2023. maximum number of sounds is exceeded, the kernel knows in which order to 
  2024. drop sounds.
  2025.  
  2026. The DOS version supported only 8-bit mono sound.  The WIN-STK supports 8- 
  2027. and 16-bit source sounds in both mono and stereo, and can play using drivers in 
  2028. 8- or 16-bit, mono or stereo modes.  It will perform all necessary conversions.
  2029.  
  2030. The DOS version was restricted to sounds smaller than 64K.  Both the 16- and 
  2031. 32-bit WIN-STK DLLs support sounds up to 4G in length.
  2032.  
  2033. The 32-bit WIN-STK DLL can trap exceptions caused by invalid user-supplied 
  2034. pointers, and flag them with an error return value.
  2035.  
  2036. For WIN-STK version 1, music is played directly from .MID files on disk.  
  2037. Version 2 will play from memory and provide interactivity and runtime control 
  2038. of music.  Therefore, we say a temporary goodbye to the .DWM file (it will 
  2039. return!)  There is also no control of FM-instrument patches with the WIN-STK.
  2040. Errors
  2041. Many errors are unnecessary under Windows, and have been eliminated.  We've 
  2042. added some new ones too.  As with the DOS version, the main manual lists all 
  2043. possible errors which can be flagged by each routine.
  2044.  
  2045. You might want to read the Error listing in the Reference section.
  2046. Samples
  2047. PLAYSTK.C
  2048. PLAYSTK.BAS
  2049. PLAYSTK.PAS
  2050.  
  2051. The samples all compile into PLAY16.EXE or PLAY32.EXE, which is a single 
  2052. sample applet for both music and sound.
  2053. Utility Programs
  2054. We eliminated VOC2DWD.EXE (VOC files are dying along with DOS) and 
  2055. MID2DWM.EXE (this version of the WIN-STK does not use .DWM files).
  2056.  
  2057. We now provide WAV2DWD.EXE, which functionality is also available to 
  2058. your application on-line via the WIN-STK library.
  2059.